﻿using System;
using System.Collections.Generic;
using System.Linq;
using Kinban.Contracts;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Kinban.TfsUtility
{
    public class TfsAccess : ITfsGateway
    {
        private readonly string _tfsProjectPortalUrl;

        public TfsAccess(string tfsProjectPortalUrl)
        {
            _tfsProjectPortalUrl = tfsProjectPortalUrl;
        }

        #region ITfsGateway Members

        public List<Story> GetStories(List<string> projectNames)
        {
            var workItems = GetProjectWorkItems(projectNames.First());

            var stories = workItems
                .Cast<WorkItem>()
                .Select(w => TranslateWorkItemToStory(w));

            return stories.ToList();
        }

        public void UpdateStory(Story story)
        {
            var workItemStore = GetWorkItemStore();

            var query = string.Format("SELECT * " +
                                      "  FROM WorkItems " +
                                      " WHERE [Id]    = '{0}' ", story.Id);
            var workItems = workItemStore.Query(query);

            foreach (WorkItem workItem in workItems)
            {
                workItem.State = story.State;
                workItem.Fields["Start Date"].Value = story.StartDate;
                workItem.Fields["Finish Date"].Value = story.EndDate;
                workItem.Fields["Assigned to"].Value = story.AssignedTo;
                workItem.Save();
            }
        }

        #endregion

        private WorkItemStore GetWorkItemStore()
        {
            // initialize TFS Project collection 
            TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(_tfsProjectPortalUrl));
            tpc.Authenticate();
            return tpc.GetService<WorkItemStore>();
        }

        private WorkItemCollection GetProjectWorkItems(string projectName)
        {
            WorkItemStore workItemStore = GetWorkItemStore();

            var query = string.Format("SELECT * " +
                                      "  FROM WorkItems " +
                                      " WHERE [Work Item Type]  = 'User Story' " +
                                      "   AND [Team Project]    = '{0}' " +
                                      " ORDER BY [Changed Date] DESC", projectName);
            WorkItemCollection wiCollection = workItemStore.Query(query);

            return wiCollection;
        }

        private Story TranslateWorkItemToStory(WorkItem workItem)
        {
            var revisions = workItem.Revisions[workItem.Revisions.Count - 1];
            var assignedTo = revisions.Fields["Assigned To"].Value.ToString();

            Story result;

            try
            {
                result = new Story
                {
                    Description = workItem.Title,
                    AssignedTo = assignedTo,
                    Id = workItem.Id,
                    DescriptionLong = workItem.Description,
                    State = workItem.State,
                    StartDate = (DateTime?)revisions.Fields["Start Date"].Value,
                    EndDate = (DateTime?)revisions.Fields["Finish Date"].Value,
                    StackRank = (double?)revisions.Fields["Stack Rank"].Value,
                };
            }
            catch (Exception ex)
            {
                result = new Story
                {
                    Id = workItem.Id,
                    ErrorOccurred = true,
                    ErrorMessage = "Service Exception: " + ex.Message 
                };
            }

            return result;
        }
    }
}
